<template>
  <el-dialog :visible="showVisible" center :show-close="false" width="960px">
    <div class="b g3 f16 tl" slot="title">
      <div class="ks-row-between pl15 pr15">
        <span>{{ title }}</span>
        <span class="el-icon-close g9 f26 poi" @click="handleCancel"></span>
      </div>
    </div>
    <el-form
      class="pl30 pr30"
      :model="formData"
      inline
      size="mini"
      ref="Form"
      label-position="left"
    >
      <el-form-item
        prop="name"
        label="规则名称"
        :rules="[
          { required: true, message: '请输入规则名称', trigger: 'blur' },
        ]"
      >
        <el-input
          v-model="formData.name"
          placeholder="请输入规则名称"
        ></el-input>
      </el-form-item>
      <el-form-item prop="ruletype" label="规则类型">
        <el-radio-group v-model="formData.ruletype">
          <el-radio-button label="form">表单</el-radio-button>
          <el-radio-button label="js">脚本</el-radio-button>
        </el-radio-group>
      </el-form-item>
      <div v-if="formData.ruletype === 'form'">
        <el-form-item
          prop="formkey"
          key="formkey"
          label="关联表单"
          :rules="[
            { required: true, message: '请选择关联表单', trigger: 'blur' },
          ]"
        >
          <el-select
            placeholder="选择提交表单标识"
            v-model="formData.formkey"
            clearable
            @change="changeForm"
          >
            <el-option
              :value="i.key"
              :label="i.label"
              v-for="(i, index) in getFormListInTree"
              :key="index"
            ></el-option>
          </el-select>
        </el-form-item>
      </div>
      <template v-else>
        <el-button size="mini" type="primary" @click="addRuleForm">
          添加
          <i class="el-icon-plus"></i>
        </el-button>
        <div v-for="(item, index) in formData.jsRuleForm" :key="index">
          <el-form-item
            :prop="'jsRuleForm.' + index + '.formkey'"
            label="关联表单"
            :rules="[
              { required: true, message: '请选择关联表单', trigger: 'change' },
            ]"
          >
            <el-select
              placeholder="选择提交表单标识"
              v-model="item.formkey"
              clearable
            >
              <el-option
                :disabled="hasFormkey(i.key)"
                :value="i.key"
                :label="i.label"
                v-for="(i, index) in getFormListInTree"
                :key="index"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-form-item
            :prop="'jsRuleForm.' + index + '.formcode'"
            label="关联字段"
            :rules="[
              { required: true, message: '请选择关联字段', trigger: 'change' },
            ]"
          >
            <el-select
              filterable
              allow-create
              @visible-change="(f) => changeRule(f, item)"
              multiple
              placeholder="选择提交表单标识"
              v-model="item.formcode"
              clearable
            >
              <el-option
                :value="i.code"
                :label="i.name"
                v-for="i in item.codelist"
                :key="i.code"
              ></el-option>
            </el-select>
          </el-form-item>
          <el-button
            v-if="index > 0"
            type="text"
            icon="el-icon-delete"
            @click="formData.jsRuleForm.splice(index, 1)"
          ></el-button>
        </div>
        <el-form-item
          label="自定义函数"
          prop="customFun"
          key="customFun"
          :rules="[
            { required: true, message: '请输入自定义函数', trigger: 'change' },
          ]"
        >
          <div class="ks-row-middle g6 poi codebg ks-col" @click="editJsx()">
            <div class="g9 f12 ks-col pl5 pr5">
              {{
                formData.customFun
                  ? "export default function..."
                  : "（空）点击添加自定义函数"
              }}
            </div>
          </div>
        </el-form-item>
      </template>
    </el-form>
    <el-main
      class="rule-editor"
      v-if="!!formData.formkey && formData.ruletype === 'form'"
    >
      <div class="rule-editor__title">
        <div class="title"></div>
        <el-button-group class="rule-editor__button-group">
          <el-button size="medium" type="primary" @click="compileRule('and')"
            >and</el-button
          >
          <el-button size="medium" type="primary" @click="compileRule('or')"
            >or</el-button
          >
          <el-button size="medium" type="primary" @click="compileRule('clear')"
            >clear</el-button
          >
        </el-button-group>
      </div>
      <div class="ruleHeader">
        <span class="ruleNav"> </span>
        <div class="rule-header__column">
          <span class="ruleNav leftNav">左值</span>
          <span class="ruleNav centerNav">
            运算符
            <el-tooltip placement="bottom" effect="light">
              <div slot="content">
                <p>运算符说明：</p>
                <p>1. =、≠：判断左右值是否相等</p>
                <p>2. ＞、≥、＜、≤：比较数值、日期的大小</p>
                <p>
                  3.
                  属于、不属于：判断左值是否在右值范围内，用于数值、日期或时间
                </p>
                <p>4. 匹配、不匹配：判断左值是否完整包含右值中的字符</p>
                <p>
                  5.
                  包含、不包含：使用正则表达式匹配左值中满足条件的数据，用于人员、部门、关联选择-数据字典和关联选择-业务模型
                </p>
                <p>6. 为空、不为空：判断左值是否为空值</p>
              </div>
              <i class="el-icon-question" />
            </el-tooltip>
          </span>
          <span class="ruleNav rightNav">右值</span>
        </div>
      </div>
      <!--      规则list-->
      <div class="ruleList">
        <!--        需要遍历-->
        <div class="ruleTree">
          <template v-for="(tree, index) in compileRuleTree">
            <!--          两层-->
            <div
              :key="'ruleTree' + index"
              v-if="tree.level === 2"
              class="group hasCompile twoLevel"
              :class="{ twoLevel: tree.level === 2 }"
            >
              <!--            规则item-->
              <div class="ruleItem orCondition">
                <div
                  class="line"
                  :class="{
                    first_line: groupIndex === 0,
                    last_line: groupIndex === tree.children.length - 1,
                  }"
                  v-for="(group, groupIndex) in tree.children"
                  :key="'group' + groupIndex"
                >
                  <!--                level为2下的 level 为1-->
                  <div v-if="group.level === 1" class="ruleTree">
                    <!--                  遍历condition item-->
                    <div
                      v-for="(item, itemIndex) in group.children"
                      :key="'ruleItem' + itemIndex"
                      class="group hasCompile"
                    >
                      <rule-item
                        class="orCondition"
                        :model-code="modelCode"
                        :modelVariableList="fieldList"
                        :config="item"
                        :all-list="group.children"
                        :index="itemIndex"
                        :parent="group"
                        @deleteRuleHander="deleteRuleHander"
                      >
                      </rule-item>
                    </div>
                    <a
                      v-if="group.logicType"
                      class="iconAndOr"
                      :class="{
                        orConditionNode: group.logicType === 'or',
                      }"
                      >{{ group.logicType }}</a
                    >
                    <scissors
                      :scissorsIndex="groupIndex"
                      :parent="tree"
                      :scissors="group"
                      @scissorsHandle="scissorsHandle"
                    ></scissors>
                  </div>
                  <!--                  level为2下的直接的rule-->
                  <template v-else>
                    <rule-item
                      class="orCondition reset_line"
                      :model-code="modelCode"
                      :modelVariableList="fieldList"
                      :config="group"
                      :all-list="tree.children"
                      :index="groupIndex"
                      :parent="tree"
                      @deleteRuleHander="deleteRuleHander"
                    >
                    </rule-item>
                  </template>
                </div>
              </div>
              <a
                v-if="tree.logicType"
                class="iconAndOr"
                :class="{ orConditionNode: tree.logicType === 'or' }"
              >
                {{ tree.logicType }}</a
              >
              <scissors
                :scissorsIndex="index"
                :parent="null"
                :scissors="tree"
                @scissorsHandle="scissorsHandle"
              ></scissors>
            </div>
            <!--          一层-->
            <div
              :key="'ruleTree' + index"
              v-else-if="tree.level === 1"
              class="group hasCompile"
            >
              <div class="ruleItem orCondition">
                <el-checkbox
                  :checked="tree.checked"
                  class="ruleCheck"
                  @change="(val) => onRuleCheckChange(tree, val)"
                  style="left: -42px"
                >
                </el-checkbox>
                <rule-item
                  v-for="(item, itemIndex) in tree.children"
                  :key="'ruleItem' + itemIndex"
                  class="orCondition"
                  :model-code="modelCode"
                  :modelVariableList="fieldList"
                  :config="item"
                  :all-list="tree.children"
                  :index="itemIndex"
                  :parent="tree"
                  @deleteRuleHander="deleteRuleHander"
                >
                </rule-item>
              </div>
              <a
                v-if="tree.logicType"
                class="iconAndOr"
                :class="{ orConditionNode: tree.logicType === 'or' }"
              >
                {{ tree.logicType }}
              </a>
              <scissors
                :scissorsIndex="index"
                :parent="null"
                :scissors="tree"
                @scissorsHandle="scissorsHandle"
              ></scissors>
            </div>
          </template>
        </div>
      </div>

      <!--          noCompile的部分 listRules-->
      <div
        class="ruleTree"
        v-for="(tree, index) in listRules"
        :key="'noCompileTree' + index"
      >
        <template>
          <div class="group noCompile">
            <rule-item
              class="orCondition"
              :model-code="modelCode"
              :modelVariableList="fieldList"
              :config="tree"
              :all-list="listRules"
              :index="index"
              :parent="null"
              @deleteRuleHander="deleteRuleHander"
              @ruleCheckChange="onRuleItemCheckChange"
            >
            </rule-item>
          </div>
        </template>
      </div>
      <div class="tl">
        <el-button
          icon="el-icon-plus"
          type="primary"
          plain
          style="border-style: dashed"
          @click="addConditionForm"
          >添加过滤条件
        </el-button>
      </div>
    </el-main>

    <div slot="footer" class="tr">
      <el-button @click="handleCancel">取 消</el-button>
      <el-button type="primary" @click="validate">保 存</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { getHmentitymodelList } from "@/apis/paas/HmEntityModelController.js";
import { treeToArray } from "@/utils/util";
import ruleItem from "./ruleItem";
import { cloneDeep } from "lodash";
import ruleToDeal from "./ruleMixins";
import scissors from "./scissors";
import moment from "moment";
import monacoEditor from "../../../hlTableList/monacoEditor/index.js";
import { TABLE_RETAIN_CODE } from "@/utils/const";
const template = `/**
 * context    页面工具类对象,
 * rootScope  页面公共事件对象
 * @returns Boolean
 */
function getRulefun(context,rootScope) {
  return true
}`;
export default {
  name: "Condition",
  components: {
    scissors,
    ruleItem,
  },
  data() {
    return {
      getFormListInTree: [],
      formData: {
        formkey: "",
        name: "",
        ruletype: "form",
        customFun: "",
        jsRuleForm: [],
      },
      activeName: "rule",
      modelCode: "",
      showVisible: false,
      allFieldList: [],
      fieldList: [], // 规则字段
      listRules: [],
      compileRuleTree: [],
      compileRuleIds: [], // 记录被checked的ruleid
      loading: false,
      title: "新建组件显示规则",
      callback: () => {},
    };
  },
  methods: {
    hasFormkey(key) {
      return this.formData.jsRuleForm.some(({ formkey }) => formkey === key);
    },
    addRuleForm() {
      this.formData.jsRuleForm.push({
        codelist: [],
        formkey: "",
        formcode: [],
      });
    },
    async changeRule(show, item) {
      if (!show) return;
      let { modelCode } = this.getFormListInTree.find(
        (i) => i.key === item.formkey
      );
      if (!modelCode) return;
      let codelist = await getHmentitymodelList({
        modelKey: modelCode,
        activated: true,
      });
      item.codelist = codelist.filter((i) => !i.builtIn);
    },
    editJsx() {
      let tem = this.formData.customFun || template;
      let jsx = decodeURIComponent(tem).replace(
        /getRulefun\([\w,\{\}]+\)/,
        `getRulefun(context,rootScope,${this.getFunparmse()})`
      );
      monacoEditor.showEdit(jsx).then((res) => {
        this.formData.customFun = encodeURIComponent(res);
        this.$refs.Form.validateField("customFun");
      });
    },
    getFunparmse() {
      return this.formData.jsRuleForm.map((i) => `{${i.formcode + ""}}`) + "";
    },
    async changeForm(v) {
      try {
        let { modelCode } = this.getFormListInTree.find((i) => i.key === v);
        this.reset();
        this.modelCode = modelCode;
        await this.loadFieldList(modelCode);
      } catch (error) {}
    },
    reset() {
      this.showVisible = true;
      this.listRules = [];
      this.compileRuleTree = [];
      this.fieldList = [];
      this.allFieldList = [];
      this.modelCode = "";
    },
    async init(getFormListInTree) {
      this.title = "新建组件显示规则";
      this.getFormListInTree = getFormListInTree;
      this.formData.formkey = "";
      this.formData.name = "";
      this.formData.customFun = "";
      this.formData.ruletype = "form";
      this.formData.jsRuleForm = [
        {
          codelist: [],
          formkey: "",
          formcode: [],
        },
      ];
      this.reset();
      this.$nextTick(() => {
        this.$refs.Form.clearValidate();
      });
      return {
        then: (callback) => {
          if (typeof callback === "function") {
            this.callback = callback;
          }
        },
      };
    },
    async enitinit(formRule = {}, getFormListInTree) {
      let { formkey, name, formatData, ruletype, customFun, jsRuleForm } =
        cloneDeep(formRule);
      this.title = "编辑组件显示规则";
      this.reset();
      this.getFormListInTree = getFormListInTree;
      this.formData.name = name;
      this.formData.ruletype = ruletype || "form";
      if (this.formData.ruletype === "js") {
        this.formData.formkey = "";
        this.formData.customFun = customFun || "";
        this.formData.jsRuleForm = jsRuleForm || [
          {
            codelist: [],
            formkey: "",
            formcode: [],
          },
        ];
        this.formData.jsRuleForm.forEach((i) => {
          this.changeRule(true, i);
        });
      } else {
        this.formData.customFun = "";
        this.formData.jsRuleForm = [
          {
            codelist: [],
            formkey: "",
            formcode: [],
          },
        ];
        this.formData.formkey = formkey;
        await this.changeForm(formkey);
        var format = cloneDeep(formatData);
        if (!format?.length && format.leftVariable) {
          this.initTransferSingle(format);
          this.listRules = [format];
        } else {
          this.compileRuleTree = this.formatInitData(format ? [format] : []);
        }
      }
      await this.$nextTick();
      this.$refs.Form.clearValidate();
      return {
        then: (callback) => {
          if (typeof callback === "function") {
            this.callback = callback;
          }
        },
      };
    },
    async loadFieldList(modelCode) {
      if (!modelCode) return;
      const list = await getHmentitymodelList({
        modelKey: modelCode,
        activated: true,
      });
      this.allFieldList = list;
      this.fieldList = list.filter(
        (item) =>
          TABLE_RETAIN_CODE.indexOf(item.type) > -1 &&
          !item.builtIn &&
          item.relationType !== "BUSINESS"
      );
    },
    handleCommandChangeRightType(command, item) {
      item.rightVariable.type = command;
    },
    addConditionForm() {
      const item = {
        id: "",
        leftVariable: {
          type: "", // 节点类型
          name: "", // 节点文本
          value: "", // 节点类型值
        },
        operator: "", // 运算符
        rightVariable: {
          type: "", // 节点类型
          name: "", // 节点文本
          value: [""], // 节点类型值
          // display_bos: []
        },
        checked: false,
        describe: "ruleLine",
        rule_id: new Date().getTime(),
        type: "condition",
      };
      this.listRules.push(item);
    },
    deleteRuleHander(data) {
      function deleteCb(data) {
        data.parent.rule_id = data.allList[0].rule_id;
      }

      ruleToDeal.deleteRuleHander(
        data,
        this.compileRuleTree,
        this.listRules,
        this,
        deleteCb
      );
    },
    // group checkbox勾选
    onRuleCheckChange(item, val) {
      item.checked = val;
      ruleToDeal.ruleCheckChange(item, this.compileRuleIds, "rule_id");
    },
    // ruleItem的checkbox点击处理
    onRuleItemCheckChange(item) {
      ruleToDeal.ruleCheckChange(item, this.compileRuleIds, "rule_id");
    },
    // compile  rule规则
    compileRule(type) {
      const data = {
        type,
        compileRuleTree: this.compileRuleTree,
        listRules: this.listRules,
        compileRuleIds: this.compileRuleIds,
        maxLevel: this.getLevelRes(),
        attribute: "rule_id",
      };
      const res = ruleToDeal.compileRule(data);
      // [listRules, compileRuleTree, maxLevel]
      if (res && res.length > 1) {
        // 清空数据，避免触发union-select中的watch清空value
        this.$set(this, "listRules", []);
        this.$set(this, "compileRuleTree", []);
        this.$nextTick(() => {
          this.$set(this, "listRules", JSON.parse(JSON.stringify(res[0])));
          this.$set(
            this,
            "compileRuleTree",
            JSON.parse(JSON.stringify(res[1]))
          );
          this.$set(this, "compileRuleIds", []);
        });
      }
    },
    getLevelRes() {
      // 遍历树  获取id数组
      const list = treeToArray(this.compileRuleTree);
      let level = 1;
      list.forEach((item) => {
        if (this.compileRuleIds.includes(item.rule_id)) {
          level = 2;
        }
      });
      return level;
    },
    async validate() {
      await this.$refs.Form.validate();
      if (this.formData.ruletype === "js") {
        if (!this.formData.customFun) {
          this.$message.warning("请填写自定义脚本！");
          return;
        }
        let { jsRuleForm } = this.formData;
        this.formData.jsRuleForm = jsRuleForm.map((i) => ({
          ...i,
          codelist: [],
        }));

        this.callback(cloneDeep(this.formData));
        this.showVisible = false;
        return;
      }
      const submitRuleData = [...this.compileRuleTree, ...this.listRules];
      if (!submitRuleData.length) {
        this.$message.warning("请至少添加一个过滤条件!");
        return;
      }
      const validateForm = this.validateRule(submitRuleData);
      // 一条数据没有也能保存
      const isRuleEditorValid =
        (validateForm && submitRuleData.length === 1) ||
        submitRuleData.length === 0;
      let confirmText = "";
      if (isRuleEditorValid) {
        // 校验通过
        let filters = [];
        if (this.listRules.length) {
          // 只有一条的情况
          const id = new Date().getTime();
          filters = [...this.listRules];
        } else {
          filters = cloneDeep(this.compileRuleTree);
        }
        const formatData = this.formatDataForSave(filters) || [];
        this.callback(
          Object.assign({ formatData: formatData[0] || [] }, this.formData)
        );
        this.showVisible = false;
      } else {
        this.activeName = "rule";
        if (submitRuleData.length > 1) {
          confirmText = validateForm
            ? "请设置所有规则条件的逻辑关系！"
            : "请将所有规则条件填写完整";
        } else {
          confirmText = "请将所有规则条件填写完整";
        }
      }
      if (confirmText) {
        this.$confirm(confirmText, "", {
          confirmButtonText: "关闭",
          showCancelButton: false,
          type: "warning",
        });
      }
    },
    validateRule(list) {
      let flag = true;

      function run(data) {
        return data.reduce(
          (acc, val) =>
            val.logicType ? acc.concat(run(val.children)) : acc.concat(val),
          []
        );
      }

      const runList = run(list);
      for (let i = 0, len = runList.length; i < len; i++) {
        if (runList[i].describe === "expression") {
          runList[i].value ? (flag = true) : (flag = false);
        } else {
          if (runList[i]?.leftVariable?.value && runList[i].operator) {
            // 不需要值的运算符
            const flagParams = ["isNull", "isNotNull"];
            if (
              !flagParams.includes(runList[i].operator) &&
              runList[i].rightVariable.value[0] === undefined
            ) {
              flag = false;
              break;
            }
            // 如果是数值
            if (
              (runList[i].leftVariable.type === "NUMBER" ||
                runList[i].leftVariable.type === "INTEGER") &&
              !flagParams.includes(runList[i].operator) &&
              runList[i]?.rightVariable?.value[0] !== undefined &&
              (runList[i].operator === "notBetween" ||
                runList[i].operator === "between")
            ) {
              const decimalData = runList[i].rightVariable.value;
              if (decimalData.length < 2) {
                flag = false;
                break;
              }
            }
          } else {
            flag = false;
            break;
          }
        }
      }
      return flag;
    },
    // 生成保存的格式
    transferSingle(item) {
      const typeArr = ["STAFF", "DEPARTMENT", "RELATION_SELECT"];
      if (item.rightVariable && item.rightVariable.value) {
        let value = item.rightVariable.value;
        const rightType = item.rightVariable.type;
        const leftType = item.leftVariable.type;
        if (rightType === "SYS_VAR") {
          item.rightVariable.value = value.join(",");
          return;
        }
        if (typeArr.includes(leftType)) {
          if (value) {
            item.rightVariable.value = value.map((val) => `[${val}]`).join("|");
          }
        } else {
          // 时间转时间戳
          if (leftType === "DATE") {
            value = value.map((item) => {
              return new Date(item).getTime();
            });
          }
          item.rightVariable.value = value.join(",");
        }
      }
    },
    formatDataForSave(data) {
      data.forEach((item) => {
        this.transferSingle(item);
        if (item.children?.length > 1) {
          this.formatDataForSave(item.children);
        }
      });
      return data;
    },

    formatInitData(data) {
      if (!data) return [];
      data.forEach((item) => {
        this.initTransferSingle(item);
        if (item.children?.length > 1) {
          this.formatInitData(item.children);
        }
      });
      return data;
    },

    initTransferSingle(item) {
      const typeArr = ["STAFF", "DEPARTMENT", "RELATION_SELECT"];
      if (item.rightVariable && item.rightVariable.value) {
        let value = item.rightVariable.value;
        const leftType = item.leftVariable.type;
        if (typeArr.includes(leftType) && item.rightVariable.type === "FIX") {
          if (value) {
            const arr = value.match(/\w+/g) || [];
            // 字典不是数字
            const field = this.allFieldList.filter(
              (field) => field.code === item.leftVariable.value
            );
            if (field?.length && field[0].type === "RELATION_SELECT") {
              item.rightVariable.value = arr;
            } else {
              item.rightVariable.value = arr.map((i) => Number(i));
            }
          }
        } else {
          value = value.split(",");
          // 时间转时间戳
          if (leftType === "DATE") {
            value = value.map((valueItem) => {
              return moment(Number(valueItem)).format("YYYY-MM-DD HH:mm:ss");
            });
          } else if (leftType === "NUMBER" || leftType === "INTEGER") {
            value = value.map((valueItem) => {
              return Number(valueItem);
            });
          }
          item.rightVariable.value = value;
        }
      }
    },
    // 移除规则关系
    scissorsHandle(data) {
      const maxLevel = 1;
      ruleToDeal.scissorsHandle(
        data,
        this.compileRuleTree,
        this.listRules,
        maxLevel
      );
    },
    // 勾选字段
    // handleSelectionChange(val) {
    //   this.fieldSelection = val;
    // },
    // 获取勾选的字段
    // getFieldSelection(blackList) {
    //   this.fieldSelection = this.permFieldList.filter(
    //     (item) => !blackList.includes(item.code)
    //   );
    //   this.toggleSelection(this.fieldSelection);
    // },

    toggleSelection(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.table.toggleRowSelection(row);
        });
      } else {
        this.$refs.table.clearSelection();
      }
    },
    // getFieldBlackList() {
    //   const res = [];
    //   this.permFieldList.forEach((item) => {
    //     const index = this.fieldSelection.findIndex(
    //       (field) => field.code === item.code
    //     );
    //     if (index < 0) {
    //       res.push(item.code);
    //     }
    //   });
    //   return res;
    // },
    handleCancel() {
      this.showVisible = false;
      this.compileRuleTree = [];
      this.listRules = [];
      this.activeName = "rule";
    },
  },
};
</script>

<style scoped lang="scss">
.codebg {
  border: 1px solid #f1f1f1;
  width: 200px;
  &:hover {
    background-color: #f3f9ff;
  }
}
</style>
<style>
.rule-editor {
  line-height: 32px;
  position: relative;
  font-size: 14px;
}

.rule-editor .rule-editor__title {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

.rule-editor .rule-editor__title .title {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  color: #1f2329;
  font-weight: 700;
  padding: 0 0 8px;
  line-height: normal;
  text-align: left;
  vertical-align: middle;
  display: inline-block;
}

.rule-editor .rule-editor__title .rule-editor__button-group {
  display: inline-table;
}

.rule-editor__button-group .el-button {
  height: 32px;
}

.rule-editor .ruleHeader {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

.rule-editor .ruleHeader .ruleNav {
  display: inline-block;
  width: 18px;
  color: #646a73;
  text-align: left;
  margin-right: 10px;
}

.rule-editor .ruleHeader .rule-header__column {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

.rule-editor .ruleHeader .rule-header__column .leftNav,
.rule-editor .ruleHeader .rule-header__column .rightNav {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  width: auto;
}

.rule-editor .ruleHeader .rule-header__column .rightNav {
  margin-right: 30px;
}

.rule-editor .ruleHeader .rule-header__column .centerNav {
  width: 110px;
}

.rule-editor .ruleList {
  margin-top: 10px;
}

.rule-editor .ruleList .ruleItem {
  position: relative;
  /*todo*/
  /*margin-left: 10px;*/
  margin-left: 7px;
  margin-bottom: 10px;
}

.rule-editor .ruleList .ruleItem .ruleCheck {
  position: absolute;
  left: -8px;
}

.rule-editor .ruleList .ruleItem .app-flowdelete {
  cursor: pointer;
}

.rule-editor .ruleList .twoLevel .group.hasCompile {
  margin-left: 15px;
  /*margin-bottom: 20px;*/
  /*border-left: 1px dashed #ccc*/
}

.rule-editor .ruleList .twoLevel div.ruleTree {
  border-left: 1px dashed #ccc;
}

.rule-editor .ruleList .group.hasCompile .ruleCheck {
  top: 50%;
  left: -52px;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.rule-editor .ruleList .group.hasCompile.twoLevel .group.hasCompile,
.rule-editor .ruleList .group.hasCompile.twoLevel {
  margin-left: 0;
}

.rule-editor .ruleList .group.hasCompile.twoLevel .group.hasCompile .ruleItem {
  position: relative;
}

.rule-editor
  .ruleList
  .group.hasCompile.twoLevel
  .group.hasCompile
  .ruleItem:first-of-type:after {
  content: "";
  position: absolute;
  left: -42px;
  top: 1px;
  width: 5px;
  height: 50%;
  background-color: #fff;
  z-index: 99;
}

.rule-editor
  .ruleList
  .group.hasCompile.twoLevel
  .group.hasCompile
  .ruleItem:last-of-type:after {
  content: "";
  position: absolute;
  left: -42px;
  bottom: 1px;
  width: 5px;
  height: 50%;
  background-color: #fff;
}

.rule-editor .ruleList .group.hasCompile.twoLevel > .ruleItem > .iconAndOr {
  left: -26px;
}

/*todo*/
.rule-editor .ruleList .twoLevel .ruleItem:not(.noCompile) {
  margin-left: 15px;
}

.rule-editor .ruleList .ruleItem:not(.noCompile) .groupChildren:not(.singel) {
  position: relative;
}

.rule-editor
  .ruleList
  .ruleItem:not(.noCompile)
  .groupChildren:not(.singel):first-of-type:before,
.rule-editor
  .ruleList
  .ruleItem:not(.noCompile)
  .groupChildren:not(.singel):last-of-type:before {
  content: "";
  position: absolute;
  left: -20px;
  top: 16px;
  width: 6px;
  height: 2px;
  background-color: #ccc;
  z-index: 100;
}

.rule-editor
  .ruleList
  .ruleItem:not(.noCompile)
  .groupChildren:not(.singel):first-of-type:after {
  content: "";
  position: absolute;
  left: -32px;
  top: 1px;
  width: 25px;
  height: 5px;
  background-color: #fff;
  -webkit-transform: rotate(90deg);
  transform: rotate(90deg);
  z-index: 99;
}

.rule-editor
  .ruleList
  .ruleItem:not(.noCompile)
  .groupChildren:not(.singel):last-of-type:after {
  content: "";
  position: absolute;
  left: -32px;
  bottom: 1px;
  width: 25px;
  height: 5px;
  background-color: #fff;
  -webkit-transform: rotate(90deg);
  transform: rotate(90deg);
}

.rule-editor .ruleList .ruleItem:not(.noCompile) .groupChildren.singel:after {
  content: "";
  position: absolute;
  left: -22px;
  bottom: 1px;
  width: 5px;
  height: 100%;
  background-color: #fff;
}

.rule-editor .ruleFooter {
  margin-top: 20px;
  padding-left: 25px;
}

.rule-editor .ruleFooter .addRule {
  border: 1px dashed #3c8cff;
}

.rule-editor .ruleFooter .addRule,
.rule-editor .ruleFooter .addRule:focus {
  background: #fff;
  color: #306eff;
  border: 1px dashed #306eff;
  border-radius: 2px;
  width: 128px;
  font-size: 12px;
  padding: 0;
}

.rule-editor .ruleFooter .addRule:focus:hover,
.rule-editor .ruleFooter .addRule:hover {
  background: #306eff;
  color: #fff;
}

.rule-editor .ruleFooter .mr_10 {
  margin-right: 5px;
}

.rule-editor__button-group.el-button-group .el-button {
  padding: 0;
  margin-right: 0 !important;
  background: #e9f2ff;
  border: 0;
  color: #3c8cff;
}

.rule-editor__button-group.el-button-group .el-button:hover {
  background: #3c8cff;
  color: #fff;
  border-right: 0;
}

.rule-editor__button-group.el-button-group .el-button span {
  border-right: 1px solid rgba(60, 140, 255, 0.4);
  padding: 0 15px;
}

.rule-editor__button-group.el-button-group .el-button:last-child {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}

.rule-editor__button-group.el-button-group .el-button:last-child span {
  border-right: 0;
}

.rule-editor__button-group.el-button-group .el-button:first-child {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}

.rule-editor__button-group.el-button-group .el-button:not(:first-child):hover {
  margin-left: -1px;
}

.scissorsBox {
  left: -28px;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  width: 15px;
  height: 25px;
  position: absolute;
  z-index: 1000;
}

.scissorsAnd {
  left: -7px;
}

.scissorsBox .hoverActive {
  display: block;
}

.scissors-position {
  display: none;
  left: 2px;
  top: 36%;
  width: 25px;
  height: 25px;
  position: absolute;
  z-index: 99;
}

.iconAndOr {
  position: absolute;
  display: inline-block;
  width: 24px;
  height: 14px;
  top: 50%;
  left: 0;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  text-align: center;
  line-height: 12px;
  font-size: 12px;
  color: #999;
  border-radius: 2px;
  z-index: 100;
  border: 1px solid #ccc;
  background: #fff;
}

.orConditionNode {
  width: 18px;
  left: 0;
}

.ruleItem {
  position: relative;
  margin-left: 15px;
  margin-bottom: 10px;
}

.ruleItem .ruleCheck {
  position: absolute;
  top: 50%;
  left: -48px;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.el-checkbox:last-of-type {
  margin-right: 0;
}

.ruleItem .app-flowdelete {
  cursor: pointer;
}

.group {
  position: relative;
  margin-left: 20px;
}

.group.hasCompile {
  border-left: 1px dashed #ccc;
}

.group.noCompile .ruleCheck {
  left: -25px;
}

.line {
  position: relative;
  padding-left: 0;
}

.line.first_line:before,
.line.last_line:before {
  content: "";
  position: absolute;
  left: -15px;
  top: 50%;
  width: 12px;
  height: 1px;
  background-color: #ccc;
  z-index: 100;
}

.line.first_line:after {
  top: 0;
  z-index: 99;
}

.line.first_line:after,
.line.last_line:after {
  content: "";
  position: absolute;
  left: -16px;
  width: 5px;
  height: 50%;
  background-color: #fff;
}

.line.last_line:after {
  bottom: 0;
}

.twoLevel.group .group.hasCompile {
  margin-left: 0;
}

.twoLevel {
  margin-left: -4px;
  padding-left: 12px;
}

.twoLevel .ruleTree .group {
  border-left: 0;
}

.twoLevel > .ruleItem > .line:before {
  left: -28px;
}

.twoLevel > .ruleItem > .line.first_line:after,
.twoLevel > .ruleItem > .line.last_line:after {
  left: -30px;
}

.mr_10 {
  margin-right: 5px;
}

.mb_10 {
  margin-bottom: 10px;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

.mb_10 .expression-input {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  margin-right: 10px;
}

.mb_10 .rule-row {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

.mb_10 .rule-row .rule__union,
.mb_10 .rule-row {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
}

.mb_10 .rule-row .rule__union_left {
  margin-right: 10px;
}

.popper-select-prefix {
  width: 205px !important;
}

.popper-select-prefix .el-dropdown-menu__item.activate {
  color: #3c8cff;
}

.el-popper.popper-select-after {
  width: 205px !important;
  margin-left: -32px;
}

.custom__user,
.custom__user-list {
  width: calc(100% - 32px) !important;
  vertical-align: top !important;
  margin-bottom: 0 !important;
  margin-right: 0 !important;
  display: inline-block;
}

.custom__user-list .bl-select-dropdown {
  left: 316px !important;
}

.custom__user-list .bl-select-dropdown .bl-select-item {
  padding: 2px 12px !important;
}

.custom__user-list .bl-select-item-behind:after {
  top: 16px !important;
}

.wfc-app-flow_editor_main {
  width: 100%;
  height: 100%;
  border: 1px solid #e8e8e8;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  margin-top: -6px;
  border-radius: 2px;
}

.wfc-app-flow_editor_main .editor_main_tab {
  width: 210px;
  height: 100%;
  border-right: 1px solid #e8e8e8;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .el-tree-node__content
  .custom-tree-node {
  width: 76%;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .el-tree-node__content
  .custom-tree-node
  > span:first-child {
  display: block;
  width: 92%;
  overflow: hidden;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;
  -webkit-text-overflow: ellipsis;
  -moz-text-overflow: ellipsis;
  white-space: nowrap;
}

.wfc-app-flow_editor_main .editor_main_tab .editor_main_tab_top {
  padding: 16px 16px 0;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .editor_main_tab_top
  .editor_main_tab_top-tit {
  color: #1f2329;
  font-size: 14px;
  font-weight: 500;
  font-family: PingFangSC-Medium, PingFang SC;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .editor_main_tab_top
  .editor_main_tab_top-search {
  margin-bottom: 6px;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .editor_main_tab_top
  .editor_main_tab_top-search
  .el-input__inner {
  border: none;
  background: #f9f9f9;
  color: #1f2329;
  font-size: 12px;
}

.wfc-app-flow_editor_main .editor_main_tab .editor_main_tab_variable {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  overflow-y: auto;
  font-size: 14px;
  padding: 4px 0;
  width: 208px;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .editor_main_tab_variable::-webkit-scrollbar {
  width: 5px;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .editor_main_tab_variable::-webkit-scrollbar-thumb {
  border-radius: 2px;
  background: #bbb;
}

.wfc-app-flow_editor_main
  .editor_main_tab
  .editor_main_tab_variable::-webkit-scrollbar-track {
  border-radius: 2px;
}

.wfc-app-flow_editor_main .editor_main_content {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
  height: 100%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -ms-flex-direction: column;
  flex-direction: column;
}

.wfc-app-flow_editor_main .editor_main_content .editor_main_content_top {
  height: 30px;
  width: 100%;
  border-bottom: 1px solid #ccc;
  background: #fbfbfb;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: distribute;
  justify-content: space-around;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  font-size: 14px;
}

.wfc-app-flow_editor_main .editor_main_content .editor_main_content_top span {
  cursor: pointer;
  color: #646a73;
}

.wfc-app-flow_editor_main .editor_main_content .editor_main_content_input {
  -webkit-box-flex: 1;
  -ms-flex: 1;
  flex: 1;
}

.pd_15 {
  padding-left: 16px;
}

.pd_15.line:before {
  width: 18px;
}
</style>
